package cn.jobstart.controller;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.jobstart.common.BeanUtils;
import cn.jobstart.common.GetCode;
import cn.jobstart.common.SkList;
import cn.jobstart.common.StringUtil;
import cn.jobstart.common.excel.EasyPoiUtil;
import cn.jobstart.common.redis.RedisUtil;
import cn.jobstart.enums.SysOperLogBusinessTypeEnum;
import cn.jobstart.props.FileConfig;
import cn.jobstart.pubInter.*;
import cn.jobstart.pubInter.aop.SystemLog;
import cn.jobstart.pubInter.baseVO.AbstractDataVO;
import cn.jobstart.pubInter.baseVO.AbstractPageVO;
import cn.jobstart.pubInter.baseVO.DecorateModel;
import cn.jobstart.pubInter.baseVO.DecoratePageList;
import cn.jobstart.web.common.SkJsonResult;
import cn.jobstart.web.common.token.JwtsUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sunke
 * @Date 2020-12-14 19:59:07
 * @description
 */

public abstract class ApiManageController<DTO extends AbstractDTO
        , PageDTO extends AbstractPageDTO
        , T extends BaseIdDoMain<KeyType>
        , TS extends BaseSearch
        , DomainVO extends AbstractDomainVO<KeyType>
        , DetailDomainVO extends DomainVO
        , DetailVO extends AbstractDataVO<DetailDomainVO>
        , ListVO extends AbstractPageVO<DetailDomainVO>
        , KeyType> extends RestfulController<DTO, PageDTO, T, TS, DomainVO, DetailDomainVO, DetailVO, ListVO, KeyType> {


    private static boolean debug;
    private static boolean imgCodeVerification;
    private static String fileBaseUrl;
    private static JwtsUtil jwtsUtil;
    private static RedisUtil redisUtil;

    @Resource
    private FileConfig fileConfig;


    public static boolean isDebug() {
        return debug;
    }

    @Value("${debugRun}")
    public void setDebug(boolean debug) {
        ApiManageController.debug = debug;
    }

    public static boolean isImgCodeVerification() {
        return imgCodeVerification;
    }

    @Value("${imgCodeVerification}")
    public void setImgCodeVerification(boolean imgCodeVerification) {
        ApiManageController.imgCodeVerification = imgCodeVerification;
    }

    public static String getFileBaseUrl() {
        return fileBaseUrl;
    }

    @Value("${file.upload.website}")
    public void setFileBaseUrl(String fileBaseUrl) {
        ApiManageController.fileBaseUrl = fileBaseUrl;
    }

    /**
     * 得到完整的图片列表
     *
     * @param img
     * @return
     */
    public static String getIntactImg(String img) {

        if (StringUtil.isEmpty(img)) {
            return "";
        }
        if (img.toLowerCase().startsWith("http")) {
            return img;
        }

        return ApiManageController.getFileBaseUrl() + "/" + img;

    }

    /**
     * 得到完整的图片列表
     *
     * @param imgs
     * @return
     */
    public static List<String> getIntactImg(List<String> imgs) {

        if (StringUtil.isNullOrEmpty(imgs)) {
            return null;
        }

        return imgs.stream().map(item -> {

            return ApiManageController.getIntactImg(item);

        }).collect(Collectors.toList());


    }

    /**
     * 得到完整的图片列表
     *
     * @param img
     * @return
     */
    public static List<String> getImgListByImgStr(String img) {

        List<String> imgs = null;
        if (StringUtil.isNotEmpty(img)) {

            String[] imgList = img.split(",");

            imgs = new ArrayList<>();
            for (String item : imgList) {
                imgs.add(ApiManageController.getFileBaseUrl() + "/" + item);
            }

        }

        return imgs;

    }

    public static RedisUtil getRedisUtil() {
        return ApiManageController.redisUtil;
    }

    @Resource(name = "redisUtil")
    public void setRedisUtil(RedisUtil redisUtil) {
        ApiManageController.redisUtil = redisUtil;
    }

    public static JwtsUtil getJwtsUtil() {
        return ApiManageController.jwtsUtil;
    }

    @Resource(name = "jwtsUtil")
    public void setJwtsUtil(JwtsUtil jwtsUtil) {
        ApiManageController.jwtsUtil = jwtsUtil;
    }


    @ApiOperation(value = "生成下载Code", notes = "生成下载Code", httpMethod = "POST")
    @PostMapping("createExportExcelCode")
    @SystemLog(title = "生成下载Code", method = "createExportExcelCode", businessType = SysOperLogBusinessTypeEnum.OTHER_TYPE)
    public SkJsonResult<String> createExportExcelCode(@RequestBody @Valid PageDTO pageDTO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String code = GetCode.createRandom(20);

        createExportExcelConditionExtend(pageDTO,request,response);

        //10分钟有效
        getRedisUtil().set(code, JSONObject.toJSONString(pageDTO), 600);


        code = fileConfig.getBaseUrl() + getBaseRoute() + "exportExcelByCode/" + code;


        return SkJsonResult.ok().setData(code);
    }

    public void createExportExcelConditionExtend(PageDTO pageDTO,HttpServletRequest request, HttpServletResponse response){

    }


    @ApiOperation(value = "导出Excel从Code", notes = "导出Excel从Code", httpMethod = "GET")
    @GetMapping("exportExcelByCode/{code}")
    @SystemLog(title = "导出Excel从Code", method = "exportExcelByCode", businessType = SysOperLogBusinessTypeEnum.OTHER_TYPE)
    public void downloadReportByCode(@PathVariable String code, HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
        String pageDTOStr = StringUtil.toString(getRedisUtil().get(code));
        PageDTO pageDTO = JSONObject.parseObject(pageDTOStr, getPageDtoClass());
        if (StringUtil.isNullOrEmpty(pageDTO)) {
            return;
        }
        //10分钟有效
        getRedisUtil().del(code);
        TS search = map(pageDTO, getSearchClass());
        searchConditionExtend(search, request, session);

        List<T> resultList = getBaseService().getAllList(search);

        List dataList = mapList(resultList, exportExcelClass());


        exportExtend(search, resultList, dataList);


        EasyPoiUtil.excelResponse(getExportParams(), response, dataList, exportExcelClass());


        //   EasyExcelUtil.excelResponseData(getModelName(), response, dataList, exportExcelClass());
    }

    @ApiOperation(value = "从Excel导入数据", notes = "从Excel导入数据", httpMethod = "POST")
    @GetMapping("importData")
    @SystemLog(title = "从Excel导入数据", method = "importData", businessType = SysOperLogBusinessTypeEnum.OTHER_TYPE)
    public SkJsonResult importData(@RequestParam ExcelImportDTO  dto, HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
        ImportParams params = new ImportParams();


        InputStream is = new FileInputStream(fileConfig.getRoot()+ File.separator+dto.getExcelPath());


        List dataList = ExcelImportUtil.importExcel(is, importExportExcelClass(), params);
        if (StringUtil.isNullOrEmpty(dataList)) {
            return SkJsonResult.ok();
        }

        List<T> resultList = SkList.getInstance();
        dataList.stream().forEach(item -> {
            T domain = BeanUtils.copyPropertiesIgnoreNull2(item, getDomainClass());
            importExportExtendOne(domain, item,dto);
            resultList.add(domain);
        });


        importExportExtend(resultList, dataList,dto);
        if (StringUtil.isNotObjEmpty(resultList)) {
            getBaseService().batchInsert(resultList);
        }
        return SkJsonResult.ok();
    }




    public void importExportExtendOne(T domain, Object oneData,ExcelImportDTO dto) {


    }

    public void importExportExtend(List<T> resultList, List dataList,ExcelImportDTO dto) {


    }


    public Class importExportExcelClass() {
        return exportExcelClass();
    }


    public Class exportExcelClass() {
        return ExcelExport.class;
    }

    /**
     * 导出数据的扩展
     *
     * @param resultList
     * @param dataList
     */
    public void exportExtend(TS search, List<T> resultList, List dataList) {


    }


    public ExportParams getExportParams() {
        ExportParams exportParams = new ExportParams();
        exportParams.setSheetName(getModelName());

        return exportParams;

    }


    public <T, V> V mapDetail(DecorateModel<T> decorateModel, Class<V> detailVOClass) {
        return map(decorateModel, detailVOClass);
    }

    public <T, V> V mapDetail(T model, Class<V> detailVOClass) {
        return map(new DecorateModel<T>(model), detailVOClass);
    }

    public <T, V> List<V> mapListDetail(List<T> modelList, Class<V> detailVOClass) {
        if (StringUtil.isObjEmpty(modelList)) {
            return null;
        }
        List<V> returnList = SkList.getInstance();
        modelList.stream().forEach(t -> {
            returnList.add(map(new DecorateModel<T>(t), detailVOClass));
        });

        return returnList;

    }

    public <T, D, V> V mapDetail(T data, Class<D> domainVOClass, Class<V> detailVOClass) {

        return map(new DecorateModel(domainVOClass), detailVOClass);

    }

    public <T, V> V mapList(DecoratePageList<T> decoratePageList, Class<V> listVOClass) {

        return map(decoratePageList, listVOClass);

    }


}
